package cn.yunbamboos.rest.service.dto.validator;

import cn.yunbamboos.exception.AppException;
import cn.yunbamboos.rest.service.IRestService;
import cn.yunbamboos.rest.service.dto.DTO;
import cn.yunbamboos.rest.service.dto.IInDTOValidator;
import jakarta.annotation.Resource;
import jakarta.validation.ConstraintViolation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import java.util.Set;

public class InDTOValidator implements IInDTOValidator, ApplicationContextAware, InitializingBean, DisposableBean {

    private static final Logger logger = LoggerFactory.getLogger(InDTOValidator.class);

    private final LocalValidatorFactoryBean validator;

    public InDTOValidator(LocalValidatorFactoryBean validator) {
        this.validator = validator;
    }

    @Override
    public void validator(DTO dto, IRestService service) {
        if(logger.isTraceEnabled()){
            logger.trace("validator in DTO {} ", dto.getClass().getName());
        }
        Set<ConstraintViolation<DTO>> validateResult = validator.validate(dto);
        if(!validateResult.isEmpty()) {
            for (ConstraintViolation<DTO> cv : validateResult) {
                throw AppException.c("{}{}",cv.getPropertyPath(), cv.getMessage());
            }
        }
    }

    @Override
    public void destroy() throws Exception {
        validator.destroy();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        validator.afterPropertiesSet();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        validator.setApplicationContext(applicationContext);
    }

}
